﻿#第十章 线程和进程 

#1.)多进程 -------------

'''
import os

print('Process (%s) start...' % os.getpid())
# Only works on Unix/Linux/Mac:
pid = os.fork()
if pid == 0:
    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
    print('I (%s) just created a child process (%s).' % (os.getpid(), pid))

fork函数是基于Unix内核系统的
'''

# multiprocessing 跨平台版本的多进程模块
from multiprocessing import Process 
import os

isMain = __name__ == "__main__"

def run_proc(name):
	print("Run child process %s %s .." %(name,os.getpid()))
	
if isMain:
	print("Parent process %s."%os.getpid())
	p = Process(target=run_proc,args=('test',)) #创建一个进程,创建子进程传入函数和函数参数
	print("child process will start")
	p.start()
	p.join() #join()方法可以等待子进程结束后再继续往下运行，通常用于进程间的同步。所以先输出 run_proc函数的内容 再往下执行输出
	print("Child process end.")
	
#进程池  Pool  如果要启动大量的子进程，可以用进程池的方式批量创建子进程：

from multiprocessing import Pool
import os,time,random

def long_time_task(name):
	print("Run task %s(%s)..."%(name,os.getpid()))
	start = time.time();
	time.sleep(random.random()*3)
	end = time.time();
	print("Task %s runs %0.2f seconds"%(name,(end-start)))
	
if isMain:
	print("Parent process %s."% os.getpid())
	p = Pool(3)
	for i in range(4):
		p.apply_async(long_time_task,args=(i,))
		print("Waitting for all subprocesses done.")
	p.close();
	p.join()
	print("All subprocesses done")

#对Pool对象调用join()方法会等待所有子进程执行完毕，调用join()之前必须先调用close()，调用close()之后就不能继续添加新的Process了。

#子进程 不大懂后面再慢慢理解?
import subprocess

print('$ nslookup www.python.org')
r = subprocess.call(['nslookup', 'www.python.org'])
print('Exit code:', r)

'''
import subprocess
print('$ nslookup')
p = subprocess.Popen(['nslookup'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = p.communicate(b'set q=mx\npython.org\nexit\n')
print(output.decode('utf-8'))
print('Exit code:', p.returncode)
'''

#进程间通信

from multiprocessing import Process, Queue
import os, time, random

# 写数据进程执行的代码:
def write(q):
    print('Process to write: %s' % os.getpid())
    for value in ['A', 'B', 'C']:
        print('Put %s to queue...' % value)
        q.put(value)
        time.sleep(random.random())

# 读数据进程执行的代码:
def read(q):
    print('Process to read: %s' % os.getpid())
    while True:
        value = q.get(True)
        print('Get %s from queue.' % value)

if isMain:
    # 父进程创建Queue，并传给各个子进程：
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 启动子进程pw，写入:
    pw.start()
    # 启动子进程pr，读取:
    pr.start()
    # 等待pw结束:
    pw.join()
    # pr进程里是死循环，无法等待其结束，只能强行终止:
    pr.terminate()









